ast: Precise type for ast.Constant.value#14159
Conversation
|
Diff from mypy_primer, showing the effect of this PR on open source code: cibuildwheel (https://github.com/pypa/cibuildwheel)
+ cibuildwheel/projectfiles.py:73: error: Incompatible types in assignment (expression has type "str | bytes | int | float | complex | EllipsisType | None", variable has type "str | None") [assignment]
mypy (https://github.com/python/mypy)
+ mypy/fastparse.py:2063: error: Statement is unreachable [unreachable]
+ mypy/fastparse.py:2063: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-unreachable for more info
werkzeug (https://github.com/pallets/werkzeug)
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "bytes" [operator]
+ src/werkzeug/routing/rules.py:779: note: Possible overload variants:
+ src/werkzeug/routing/rules.py:779: note: def __add__(self, str, /) -> str
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "int" [operator]
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "float" [operator]
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "complex" [operator]
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "None" [operator]
+ src/werkzeug/routing/rules.py:779: error: No overload variant of "__add__" of "str" matches argument type "ellipsis" [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "str") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "int") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "float") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "complex") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "None") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("bytes" and "ellipsis") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("int" and "str") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("int" and "bytes") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("int" and "None") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("int" and "ellipsis") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("float" and "str") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("float" and "bytes") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("float" and "None") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("float" and "ellipsis") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("complex" and "str") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("complex" and "bytes") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("complex" and "None") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("complex" and "ellipsis") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported left operand type for + ("None") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("None" and "int") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("None" and "float") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("None" and "complex") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported left operand type for + ("ellipsis") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("ellipsis" and "int") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("ellipsis" and "float") [operator]
+ src/werkzeug/routing/rules.py:779: error: Unsupported operand types for + ("ellipsis" and "complex") [operator]
+ src/werkzeug/routing/rules.py:779: note: Both left and right operands are unions
flake8-pyi (https://github.com/PyCQA/flake8-pyi)
+ flake8_pyi/visitor.py:453: error: Item "bytes" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Item "int" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Item "float" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Item "complex" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Item "None" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Item "EllipsisType" of "str | bytes | int | float | complex | EllipsisType | None" has no attribute "isidentifier" [union-attr]
+ flake8_pyi/visitor.py:453: error: Argument 1 to "iskeyword" has incompatible type "str | bytes | int | float | complex | EllipsisType | None"; expected "str" [arg-type]
prefect (https://github.com/PrefectHQ/prefect)
+ src/prefect/utilities/callables.py:655: error: Incompatible return value type (got "Union[str, bytes, int, float, complex, ellipsis, None]", expected "Optional[str]") [return-value]
+ src/prefect/utilities/_ast.py:104: error: Dict entry 0 has incompatible type "str": "Union[str, bytes, int, float, complex, ellipsis, None]"; expected "str": "str" [dict-item]
|
|
It would be nice if That would fix all of the flake8-pyi errors. I've had similar thoughts about e.g. |
|
Some new errors from code that doesn't handle all kinds of constants. I think the cibuildwheel one is a real latent bug. The mypy one is fallback for unrecognized constants; it seems positive that the type system now recognizes it's unreachable. The flake8-pyi one is a false positive because there's a check that they're all strs that is not visible to the type system. The werkzeug one is manually building up a list of str ast.Constants, so it's safe but the type system doesn't recognize it. |
|
Making it generic would be troublesome because it would have to be invariant. |
Ref python/typeshed#14159 (comment) --------- Co-authored-by: Alex Waygood <[email protected]>
srittau
left a comment
There was a problem hiding this comment.
The primer hits – except from the mypy one – are all either true positives or could at least benefit from some more defensive coding.
These are the only types that Python's parser will produce.
Fixes #14156. See also python/cpython#134741.